home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1992 June: ROMin Holiday / ADC Developer CD (1992-06) (''ROMin Holiday'')_iso / Developer Connection - 06-1992.iso / Development Platforms / HyperCard Related / XCMDs & XFCNs / StackToPICSFile 1.1 / StackToPICSFile.p < prev    next >
Encoding:
Text File  |  1991-04-03  |  9.9 KB  |  384 lines  |  [TEXT/MPS ]

  1. {$R-}
  2. {$S StackToPICSFile }
  3.  
  4.     StackToPICSFile(FileName, CreatorType)
  5.  
  6.     This XFCN makes a PICS file of the current Hypercard stack’s cards.  
  7.     
  8.     A PICS file is merely a resource file with a consecutively-numbered series of
  9.     PICT resources, beginning with resource number 128.  Normally, a PICS file can 
  10.     have frame-differenced PICTs, but this XFCN does not create frame-differenced
  11.     images.  Instead, each PICT is a full image of the card it came from.
  12.         
  13.     The optional parameter CreatorType is a four-character string
  14.     which will be the creator type of the file.  This will allow the file
  15.     to be double-clicked to invoke the corresponding application.  The 
  16.     default value is '????' -- which means no application.
  17.     
  18.     If the XFCN is successful, then empty is returned, otherwise the return value
  19.     is an error message.
  20.     
  21.     How does it work?  It goes to each each card and simulates the user holding down 
  22.     the option key while selecting "Copy Card" (which places a full-size PICT image 
  23.     of the card onto the clipboard).  Then, each PICT in succession is written to the 
  24.     file.
  25.     
  26. }
  27.  
  28. UNIT DummyUnit;
  29.  
  30. INTERFACE
  31.  
  32.     USES {* ToolIntf, PackIntf, *}
  33.             ToolUtils, Resources, Packages,
  34.             Menus, Events, TextEdit, HyperXCmd, 
  35.             OSIntf, Scrap, QuickDraw,
  36.             
  37.             PICSFileRoutines;
  38.  
  39.     PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  40.  
  41. IMPLEMENTATION
  42.  
  43.     PROCEDURE StackToPICSFile(paramPtr: XCmdPtr);
  44.     FORWARD;
  45.  
  46.     PROCEDURE EntryPoint(paramPtr: XCmdPtr);
  47.     BEGIN
  48.         StackToPICSFile(paramPtr)
  49.     END { entrypoint } ;
  50.  
  51.  
  52.     PROCEDURE StackToPICSFile(paramPtr: XCmdPtr);
  53.     
  54.     CONST
  55.     
  56.     MinParams =        1;
  57.     MaxParams =        2;
  58.     
  59.     TYPE
  60.     
  61.     ParamArray =        PACKED ARRAY [1..MaxParams] OF Str255;
  62.     
  63.     VAR
  64.     
  65.     ParamStrings:            ParamArray;
  66.     
  67.     FileNameParam:            Str255;
  68.     CreatorTypeParam:        OSType;
  69.     
  70.     fileRefNum:                Integer;
  71.  
  72.     myErr:                    Integer;
  73.     ErrorMessage:            Str255;
  74.     
  75.     
  76.         PROCEDURE ExitWithMessage(aString:    Str255);
  77.         BEGIN
  78.             WITH paramPtr^ DO BEGIN
  79.                 returnValue := PasToZero(paramPtr, aString);
  80.                 EXIT(StackToPICSFile);
  81.             END;
  82.         END;
  83.  
  84.         PROCEDURE ExitWithError(aString: Str255);
  85.         BEGIN
  86.             ExitWithMessage(concat('•••••••• Error: ', aString, '.'));
  87.         END;
  88.                         
  89.         FUNCTION StackVersionLaterThan(aVersionString: Str31): Boolean;
  90.         VAR
  91.             Expression:            Str255;
  92.             EvalResult:            Handle;
  93.             ResultString:        Str255;
  94.  
  95.         BEGIN
  96.                 
  97.             StackVersionLaterThan := FALSE;
  98.                         
  99.             Expression := concat('item 4 of the version of this stack >= ',
  100.                                         aVersionString);
  101.  
  102.             EvalResult := EvalExpr(paramPtr, Expression);            
  103.             
  104.             ZeroToPas(paramPtr, EvalResult^, ResultString);
  105.             
  106.             IF (StrToBool(paramPtr, ResultString)) THEN
  107.                 StackVersionLaterThan := TRUE;
  108.         END;
  109.                         
  110.             
  111.         FUNCTION NumberOfCards: Integer;
  112.         VAR
  113.             Expression:            Str255;
  114.             EvalResult:            Handle;
  115.             ResultString:        Str255;
  116.  
  117.         BEGIN
  118.             NumberOfCards := 0;
  119.                         
  120.             Expression := concat('the number of cards in this stack');
  121.             EvalResult := EvalExpr(paramPtr, Expression);            
  122.             
  123.             ZeroToPas(paramPtr, EvalResult^, ResultString);
  124.             
  125.             NumberOfCards := LoWord(StrToNum(paramPtr, ResultString));
  126.  
  127.         END;
  128.  
  129.         FUNCTION GotoCard(CardNum: Integer): Boolean;
  130.         VAR
  131.             CardNumString:        Str255;
  132.             Expression:            Str255;
  133.  
  134.         BEGIN
  135.             GotoCard := FALSE;
  136.                         
  137.             NumToStr(paramPtr, CardNum, CardNumString);
  138.             Expression := concat('go to card ', CardNumString);
  139.             
  140.             {* Execute the hypertalk command to go to the card *}
  141.             SendCardMessage(paramPtr, Expression);
  142.             
  143.             GotoCard := TRUE;
  144.  
  145.         END;
  146.         
  147.         FUNCTION GetPICTfromClipboard(ThePict: PicHandle; VAR ErrorMessage: Str255): Boolean;
  148.         VAR
  149.             PictSize:                Integer;
  150.             ScrapOffset:            LONGINT;
  151.         BEGIN
  152.             GetPICTfromClipboard := FALSE;
  153.                         
  154.             PictSize := GetScrap(Handle(ThePict), 'PICT', ScrapOffset);    
  155.             IF (PictSize = 0) THEN 
  156.             BEGIN
  157.                 ErrorMessage := 'Pict on clipboard was of zero size';
  158.                 Exit(GetPICTfromClipboard);
  159.             END;
  160.             
  161.             IF (PictSize < 0)
  162.             THEN 
  163.             BEGIN
  164.                 IF (PictSize = NoTypeErr) THEN 
  165.                     BEGIN
  166.                         ErrorMessage := ('No data of type PICT on clipboard');
  167.                         Exit(GetPICTfromClipboard);
  168.                     END
  169.                 ELSE
  170.                     BEGIN
  171.                         ErrorMessage := ('Unknown error while getting PICT');
  172.                         Exit(GetPICTfromClipboard);
  173.                     END;
  174.             END;
  175.             
  176.             GetPICTfromClipboard := TRUE;
  177.         END;
  178.                 
  179.         FUNCTION GetMenuItemCommandKey(ItemName: Str255; MenuName: Str255): Char;
  180.         VAR
  181.             Expression:            Str255;
  182.             EvalResult:            Handle;
  183.             ResultString:        Str255;
  184.         BEGIN
  185.             Expression := concat('the cmdChar of menuitem "', ItemName, '" of menu "', MenuName, '"');
  186.             EvalResult := EvalExpr(paramPtr, Expression);            
  187.             
  188.             ZeroToPas(paramPtr, EvalResult^, ResultString);
  189.             
  190.             IF (Length(ResultString) = 0) THEN
  191.                 GetMenuItemCommandKey := Char(0)
  192.             ELSE
  193.                 GetMenuItemCommandKey := ResultString[1];
  194.         END;
  195.  
  196.         PROCEDURE SetMenuItemCommandKey(ItemName: Str255; MenuName: Str255; KeyName: Char);
  197.         VAR
  198.             Expression:            Str255;
  199.         BEGIN
  200.             Expression := concat('set the cmdChar of menuitem "', ItemName, '" of menu "', MenuName, '" to ');
  201.             IF (KeyName = Char(0)) THEN
  202.                 Expression := concat(Expression, 'empty')
  203.             ELSE
  204.                 Expression := concat(Expression, '"', KeyName, '"');
  205.             
  206.             SendHCMessage(paramPtr, Expression);
  207.         END;
  208.  
  209.         PROCEDURE TypeCharWithKeys(WhichChar: Char; ShiftKey, CmdKey, OptionKey: Boolean);
  210.         VAR
  211.             Expression:            Str255;
  212.             AlreadyUsingOneKey:    Boolean;
  213.         BEGIN
  214.             Expression := concat('type "', WhichChar, '"');
  215.             IF (ShiftKey OR CmdKey OR OptionKey) THEN
  216.             BEGIN
  217.                 Expression := concat(Expression, ' with ');
  218.                 
  219.                 AlreadyUsingOneKey := FALSE;
  220.                 
  221.                 IF (ShiftKey) THEN
  222.                 BEGIN
  223.                     IF (AlreadyUsingOneKey) THEN Expression := concat(Expression, ',');
  224.                     Expression := concat(Expression, 'shiftKey');
  225.                     AlreadyUsingOneKey := TRUE;
  226.                 END;
  227.                 
  228.                 IF (CmdKey) THEN
  229.                 BEGIN
  230.                     IF (AlreadyUsingOneKey) THEN Expression := concat(Expression, ',');
  231.                     Expression := concat(Expression, 'cmdKey');
  232.                     AlreadyUsingOneKey := TRUE;
  233.                 END;
  234.                 
  235.                 IF (OptionKey) THEN
  236.                 BEGIN
  237.                     IF (AlreadyUsingOneKey) THEN Expression := concat(Expression, ',');
  238.                     Expression := concat(Expression, 'optionKey');
  239.                     AlreadyUsingOneKey := TRUE;
  240.                 END;
  241.             END;
  242.             
  243.             SendHCMessage(paramPtr, Expression);
  244.         END;
  245.  
  246.  
  247.         FUNCTION MakeTheFrames(fileRefNum: Integer; VAR ErrorMessage: Str255): Boolean;
  248.         VAR
  249.  
  250.             OldMenuKey:            Char;
  251.             NumCards:            Integer;
  252.             Success:             Boolean;
  253.             
  254.             {* This is the callback routine that is passed to AddFramesToPICSFile.  It goes to the
  255.                 card specified by frameNum (i.e. CardNum), copies its image to the clipboard, and
  256.                 returns this image in theImage (a PicHandle);
  257.                 *}
  258.             FUNCTION GetNumberedCardImage(CardNum: Integer; VAR theImage: PicHandle; 
  259.                                                 VAR ErrorMessage: Str255): Boolean;
  260.             VAR
  261.                 Success:            Boolean;
  262.             BEGIN
  263.                 GetNumberedCardImage := FALSE;
  264.                 Success := TRUE;
  265.                 
  266.                 Success := Success AND GotoCard(CardNum);
  267.                 IF (NOT Success) THEN 
  268.                 BEGIN
  269.                     ErrorMessage := 'Problem while trying to move between cards';
  270.                     Exit(GetNumberedCardImage);
  271.                 END;
  272.                 
  273.                 {* This is the same as typing Command-8 with the option key held down
  274.                     -- and we will have already set up Command-8 to do Copy Card, so this
  275.                     will cause the card to be copied, and a full-sized picture of the 
  276.                     card to be placed on the clipboard.  There should be a callback to 
  277.                     perform this function, but as of Hypercard 2.0, there was none
  278.                     available.
  279.                     *}
  280.                 TypeCharWithKeys(Char('8'), FALSE, TRUE, TRUE);
  281.     
  282.                 Success := Success AND GetPICTfromClipboard(theImage, ErrorMessage);
  283.                 IF (NOT Success) THEN 
  284.                 BEGIN
  285.                     {* ErrorMessage was set by GetPICTfromClipboard *}
  286.                     Exit(GetNumberedCardImage);
  287.                 END;
  288.                 
  289.                 GetNumberedCardImage := Success;
  290.             END;
  291.             
  292.         BEGIN
  293.             MakeTheFrames := FALSE;
  294.             Success := TRUE;
  295.             
  296.             OldMenuKey := GetMenuItemCommandKey('Copy Card', 'Edit');
  297.             SetMenuItemCommandKey('Copy Card', 'Edit', Char('8'));
  298.                         
  299.             NumCards := NumberOfCards;
  300.             
  301.             Success := Success AND AddFramesToPICSFile(fileRefNum, NumCards, 
  302.                                             GetNumberedCardImage, ErrorMessage);
  303.             
  304.             {* Clean up *}
  305.             SetMenuItemCommandKey('Copy Card', 'Edit', OldMenuKey);
  306.             
  307.             MakeTheFrames := Success;
  308.  
  309.         END;        
  310.         
  311.         PROCEDURE ParseParams;
  312.         VAR
  313.             ParamNum:            integer;
  314.         BEGIN
  315.             WITH paramPtr^ DO 
  316.             BEGIN
  317.                 IF (paramCount < MinParams) THEN ExitWithError('Too few parameters');
  318.                 IF (paramCount > MaxParams) THEN ExitWithError('Too many parameters');
  319.                             
  320.                 ParamNum := 1; {* Required *}
  321.                 
  322.                 ZeroToPas(ParamPtr, Params[ParamNum]^, ParamStrings[ParamNum]);
  323.                 FileNameParam := ParamStrings[ParamNum];
  324.                 IF (FileNameParam = '') THEN ExitWithError('Empty file name');
  325.                 
  326.                 ParamNum := 2; {* Optional *}
  327.                 
  328.                 IF (paramCount >= ParamNum) THEN
  329.                     BEGIN
  330.                         ZeroToPas(paramPtr, params[ParamNum]^, ParamStrings[ParamNum]);  
  331.                         IF (length(ParamStrings[ParamNum]) <> 4)
  332.                         THEN ExitWithError(concat('Bad creator type (not 4 characters): ',
  333.                                 ParamStrings[ParamNum]));
  334.                         
  335.                         CreatorTypeParam[1] := ParamStrings[ParamNum][1];
  336.                         CreatorTypeParam[2] := ParamStrings[ParamNum][2];
  337.                         CreatorTypeParam[3] := ParamStrings[ParamNum][3];
  338.                         CreatorTypeParam[4] := ParamStrings[ParamNum][4];
  339.                     END
  340.                 ELSE
  341.                     BEGIN
  342.                         CreatorTypeParam := '????';
  343.                     END;    
  344.             END;
  345.         END;
  346.                         
  347.     BEGIN {StackToPICSFile}
  348.         
  349.         ParseParams; {* May perform ExitWithError if parsing fails *}
  350.         
  351.         IF (StackVersionLaterThan('02000000') = FALSE) THEN
  352.         BEGIN
  353.             ExitWithError('StackToPICSFile can only convert stacks in Hypercard 2.0 format');
  354.         END;
  355.         
  356.         IF (StartMakingPICSFile(FileNameParam, CreatorTypeParam, fileRefNum, ErrorMessage) <> TRUE) THEN
  357.         BEGIN
  358.             {* ErrorMessage is set by StartMakingPICSFile *}
  359.             ExitWithError(ErrorMessage);
  360.         END;
  361.                 
  362.         IF (MakeTheFrames(fileRefNum, ErrorMessage) <> TRUE) THEN
  363.         BEGIN
  364.             IF (FinishMakingPICSFile(fileRefNum, ErrorMessage) <> TRUE) THEN
  365.                         ExitWithError(ErrorMessage);
  366.             {* ErrorMessage is set by MakeTheFrames *}
  367.             ExitWithError(ErrorMessage);
  368.         END;
  369.         
  370.         IF (FinishMakingPICSFile(fileRefNum, ErrorMessage) <> TRUE) THEN
  371.         BEGIN
  372.             {* ErrorMessage is set by FinishMakingPICSFile *}
  373.             ExitWithError(ErrorMessage);
  374.         END;
  375.         
  376.         ExitWithMessage('');
  377.  
  378.     END { StackToPICSFile} ;
  379.  
  380. END. { DummyUnit }
  381.  
  382.  
  383.